<!-- 
DynamicTabs.vue
这是一个使用动态组件特性创建的标签页组件
动态组件的特点：
- 可以在多个组件之间动态切换
- 支持 keep-alive 缓存
- 适用于标签页、步骤向导等场景
- 可以减少重复渲染
-->
<template>
  <div class="dynamic-tabs">
    <!-- 标签页头部 -->
    <div class="dynamic-tabs__header">
      <button
        v-for="tab in tabs"
        :key="tab.name"
        class="dynamic-tabs__button"
        :class="{ 'dynamic-tabs__button--active': currentTab === tab.name }"
        @click="switchTab(tab.name)"
      >
        <IconFunction :type="tab.icon" :size="16" class="dynamic-tabs__icon" />
        {{ tab.label }}
      </button>
    </div>

    <!-- 标签页内容区 -->
    <div class="dynamic-tabs__content">
      <!-- 
        使用 keep-alive 包裹 component 元素以缓存组件状态
        include 属性指定需要缓存的组件名称
      -->
      <!-- 使用动态组件 :is 属性可以是： - 已注册组件的名字 - 导入的组件对象 -->
      <KeepAlive :include="cachedTabs">
        <component :is="currentComponent" v-bind="componentProps" @update="handleUpdate" />
      </KeepAlive>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, markRaw } from 'vue'
  import IconFunction from './IconFunction.vue'
  import ButtonOptions from './ButtonOptions.vue'
  import CardComposition from './CardComposition.vue'
  import ListSetup from './ListSetup.vue'

  // 定义标签页配置
  interface Tab {
    name: string
    label: string
    icon: 'info' | 'success' | 'warning'
    component: any
    props?: Record<string, any>
  }

  // 标签页配置
  const tabs = markRaw<Tab[]>([
    {
      name: 'button',
      label: '按钮示例',
      icon: 'info',
      component: ButtonOptions,
      props: {
        text: '动态按钮',
        type: 'primary',
      },
    },
    {
      name: 'card',
      label: '卡片示例',
      icon: 'success',
      component: CardComposition,
      props: {
        title: '动态卡片',
        content: '这是一个动态加载的卡片内容',
        lastUpdated: new Date(),
      },
    },
    {
      name: 'list',
      label: '列表示例',
      icon: 'warning',
      component: ListSetup,
      props: {
        title: '动态列表',
        items: [
          { id: 1, name: '项目 1' },
          { id: 2, name: '项目 2' },
          { id: 3, name: '项目 3' },
        ],
      },
    },
  ] as Tab[])

  // 当前激活的标签页
  const currentTab = ref<string>(tabs.length > 0 ? tabs[0]!.name : '')

  // 需要缓存的组件名称
  const cachedTabs = computed(() => tabs.map((tab) => tab.component.name))

  // 当前显示的组件
  const currentComponent = computed(
    () => tabs.find((tab) => tab.name === currentTab.value)?.component,
  )

  // 当前组件的 props
  const componentProps = computed(
    () => tabs.find((tab) => tab.name === currentTab.value)?.props || {},
  )

  // 切换标签页
  const switchTab = (tabName: string) => {
    currentTab.value = tabName
  }

  // 处理组件更新
  const handleUpdate = (event: any) => {
    console.log('组件更新:', event)
  }

  // 暴露方法给父组件
  defineExpose({
    switchTab,
  })
</script>

<style scoped>
  .dynamic-tabs {
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
  }

  .dynamic-tabs__header {
    display: flex;
    background: #f5f5f5;
    border-bottom: 1px solid #ddd;
    padding: 8px;
    gap: 8px;
  }

  .dynamic-tabs__button {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
    transition: all 0.3s ease;
  }

  .dynamic-tabs__button:hover {
    background: #e0e0e0;
  }

  .dynamic-tabs__button--active {
    background: #fff;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }

  .dynamic-tabs__icon {
    opacity: 0.7;
  }

  .dynamic-tabs__content {
    padding: 16px;
    background: white;
  }

  /* 组件切换动画 */
  .dynamic-tabs__content :deep(.v-enter-active),
  .dynamic-tabs__content :deep(.v-leave-active) {
    transition: opacity 0.3s ease;
  }

  .dynamic-tabs__content :deep(.v-enter-from),
  .dynamic-tabs__content :deep(.v-leave-to) {
    opacity: 0;
  }
</style>
